package service.impl;

import dao.AdminDao;
import dao.ExamTypeDao;
import dao.QuestionDao;
import dao.StudentDao;
import dao.impl.AdminDaoImpl;
import dao.impl.ExamTypeDaoImpl;
import dao.impl.QuestionDaoImpl;
import dao.impl.StudentDaoImpl;
import entity.Admin;
import entity.ExamType;
import entity.Question;
import entity.Student;
import exception.ExamException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import service.ExamService;
import utils.DbUtil;

import java.io.Serializable;
import java.util.List;

/**
 * Created by honghao on 2017/2/16.
 */
public class ExamServiceImpl implements ExamService {
    private static SessionFactory sf = DbUtil.getSf();
    private static StudentDao stuDao = new StudentDaoImpl();
    private static QuestionDao quDao = new QuestionDaoImpl();
    private static ExamTypeDao exDao = new ExamTypeDaoImpl();
    private static AdminDao adDao = new AdminDaoImpl();

    @Override
    public int addStudent(String stuNumber, String name, String classname, String humanId, String email, String address, String phone) throws ExamException {
        Student student = new Student(stuNumber, name, classname,
                humanId, email, address, phone);
        stuDao.save(student);

        return student.getId();
    }

    @Override
    public void deleteStudent(int id) throws ExamException {
        stuDao.delete(id);
    }

    @Override
    public List<Student> listStudent(int pageNo) throws ExamException {
        List<Student> students = stuDao.findAllByPage(pageNo, STUDENT_PAGE_SIZE);
        return students;
    }

    @Override
    public int addQuestion(String quTitle, String quHard, Integer quScore, String quAnswer, String quType, String selectOption, int examTypeId) throws ExamException {

        try {
            ExamType examType = exDao.get(examTypeId);
            if (examType == null) {
                throw new ExamException("没有这个试题类型！");
            }
            Question question = new Question(quTitle, quHard, quScore,
                    quAnswer, quType, selectOption, examType);
            quDao.save(question);
            return question.getId();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("添加试题出错！请重试！");
        }
    }

    @Override
    public void deleteQuestion(int id) throws ExamException {
        try {
            quDao.delete(id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("删除题操作错误！");
        }
    }

    @Override
    public List<Question> listQuestion(int pageNo) throws ExamException {
        List<Question> questions = quDao.findAllByPage(pageNo, QUESTION_PAGE_SIZE);
        if (questions != null) {
            return questions;
        } else {
            return null;
        }
    }

    @Override
    public void deleteExamType(int id) throws ExamException {
        try {
            exDao.delete(id);
        } catch (Exception e) {

            throw new ExamException("删除试卷错误！");
        }
    }

    @Override
    public int addExamType(String testTitle, String testTime) throws ExamException {
        ExamType examType = new ExamType(testTitle, testTime);
        exDao.save(examType);
        return examType.getId();
    }

    @Override
    public List<ExamType> getAllExamType() throws ExamException {
        List<ExamType> examTypes = exDao.findAll();
        return examTypes;
    }

    @Override
    public boolean adminLogin(String user, String pass) throws ExamException {
        List<Admin> result = adDao.findAdminByNameAndPass(user, pass);
        if (result != null && result.size() > 0) {
            return true;
        } else {

            return false;
        }
    }
    
    @Override
    public int getStudentCount() throws ExamException {
        long studentCount = stuDao.getStudentCount();
        return (int) studentCount;
    }

    @Override
    public int getQuestionCount() throws ExamException {
        return (int) quDao.getQuestionCount();
    }

    @Override
    public int getPageCount(int count, int pageSize)
    {
        return (count+pageSize-1)/pageSize;
    }

    @Override
    public String studentLogin(String name, String stuNumber) throws ExamException {
        try {
            List result = stuDao.findStudentByNameAndStuNumber(name, stuNumber);
            if(result!=null&&result.size()>0){
                return name;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("学生登录出现异常，请重试！");
        }
    }

    @Override
    public Question getNextQuestion(List<Integer> alreadys, int examTypeId) throws ExamException {
        try {
            //获取指定类型
            ExamType examType = exDao.get(examTypeId);
            if(examType==null){
                throw new ExamException("不存在该考试类型，请重新选择！");
            }
            //获取question表中最大id号
            int maxId = quDao.getMaxId();

            //直到获取1道正确的题目时才退出循环
            REPEAT_TRY:
            while(true){
                //产生一个随机数，该随机数不大于最大id
                int randomId = (int)Math.round(Math.random()*maxId)+1;
                //如果已答题的数组不为空，判断获取的题是否已在已答题数组中
                if(alreadys!=null){
                    for(int alreadyId:alreadys){
                        if(alreadyId==randomId){
                            //舍弃该随机数，继续标号为(REPEAT_TRY)的while循环的下一次循环，重新获取随机数
                            continue REPEAT_TRY;
                        }
                    }
                }
                Question question = null;
                //如果获取题目出现异常，重新开始循环来获取下一题
                try {
                    //每次用随机数取出一个题目，检查该题目是否属于指定ExamType,同时还要检查是否已经做过
                    question = quDao.findQuestionByExamType(randomId, examType);
                    if(question==null){//没有找到id为随机数的题目，继续循环直至找到
                        continue;
                    }
                } catch (Exception e) {
                    continue;
                }
                //到这里说明已正常获取一道题目，可以退出循环，将题目返回
                return question;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("获取下一道试题时出现异常，请重试！");
        }
    }

    @Override
    public Question getQuestionById(int id) throws ExamException {
        try {
            return quDao.get(id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("获取试题时出现异常，请重试！");
        }
    }

    @Override
    public String getExamTypeName(int typeId) throws ExamException {
        try {
            ExamType examType = exDao.get(typeId);
            return examType.getExamName();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ExamException("获取试题名称时出现异常，请重试！");
        }
    }
}
